#include "V9C.h"
#include "function.h"

const array<array<string,3>,3> V9C::_NineStr={
	"0","11000","11100",
	"11001","10","11010",
	"11101","11011","1111"};

V9C::V9C(void)
{
}


V9C::~V9C(void)
{
}
//_Str:object , K:length of every 9code , data/fist/last original string
void V9C::_Code(string& _Str,uint32_t K,const string& data,uint32_t first,uint32_t last)
{
	if((last-first)%K!=0)
		throw msg("V9C:_Code invalid length");
	for(;first!=last;first+=K)
	{
		_Str+=_NineCode(data,first,K>>1);
	}
}

unique_ptr<string> V9C::code(const string &data,uint32_t K)
{
	unique_ptr<string> pStr(new string);
	string _data(data);
	while(_data.length()%K!=0)
		_data.push_back('X');
	_Code(*pStr,K,_data,0,_data.length());
	//cout<<"length="<<pStr->length()<<endl;
	//cout<<*pStr<<endl;
	return pStr;
}

unique_ptr<string> V9C::vcode(const string& data,uint32_t L)
{
	unique_ptr<string> pStr(new string);
	string _data(data);
	while(_data.length()%L!=0)
		_data.push_back('X');
	vector<int> div;
	for(uint32_t i=4;i<=L;i+=2)
		if(L%i==0)
			div.push_back(i);
	//L'length information
	int bits=(int)ceil(log(div.size()*1.0)/log(2.0));
	//cout<<bits<<endl;
	for(uint32_t i=0;i!=_data.length();i+=L)
	{
		uint32_t min_len=INT_MAX,min_k;
		string min_str;
		for(uint32_t j=0;j<div.size();j++)
		for(uint32_t j=0;j<div.size();j++)
		{
			string _Tmp;
			_Code(_Tmp,div.at(j),_data,i,i+L);
			if(_Tmp.length()<min_len)
			{
				min_len=_Tmp.length();
				min_str=_Tmp;
				min_k=j;
			}
		}
		//cout<<div.at(min_k)<<endl;
		for(int k=bits-1;k>=0;k--)
			pStr->push_back((min_k>>k)&1+'0');
		pStr->append(min_str);
	}
	return pStr;
}